package no.nordicsemi.android.blinky.wekeupble;

import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.Context;
import android.util.Log;

import java.util.UUID;

import androidx.annotation.NonNull;

import no.nordicsemi.android.ble.BleManager;
import no.nordicsemi.android.ble.WriteRequest;
import no.nordicsemi.android.blinky.utils.SPUtils;

public class WakeupManager extends BleManager<WakeupManagerCallbacks> {
    private static final String TAG = WakeupManager.class.getSimpleName();
    /**
     * 服务 UUID.
     */
    public final static UUID SERVICE_UUID = UUID.fromString("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
    /**
     * 写特征 UUID.
     */
    private final static UUID WRITE_CHARACTERISTIC_UUID = UUID.fromString("6E400002-B5A3-F393-E0A9-E50E24DCCA9E");
    /**
     * 通知特征 UUID.
     */
    private final static UUID NOTIFY_CHARACTERISTIC_UUID = UUID.fromString("6E400003-B5A3-F393-E0A9-E50E24DCCA9E");


    //OTA 状态下服务及特征说明
    public final static UUID ota_service_uuid = UUID.fromString("00001234-0000-1000-8000-00805f9b34fb");

    private final static UUID otas_tx_cmd_uuid = UUID.fromString("0000ff01-0000-1000-8000-00805f9b34fb");
    private final static UUID otas_tx_dat_uuid = UUID.fromString("0000ff02-0000-1000-8000-00805f9b34fb");
    private final static UUID otas_rx_cmd_uuid = UUID.fromString("0000ff03-0000-1000-8000-00805f9b34fb");
    private final static UUID otas_rx_dat_uuid = UUID.fromString("0000ff04-0000-1000-8000-00805f9b34fb");

    private BluetoothGattCharacteristic mWriteCharacteristic, mNotifyCharacteristic;
    private BluetoothGattCharacteristic otas_tx_cmd_Characteristic, otas_tx_dat_Characteristic, otas_rx_cmd_Characteristic, otas_rx_dat_Characteristic;

    public WakeupManager(@NonNull Context context) {
        super(context);
    }

    @NonNull
    @Override
    protected BleManager.BleManagerGattCallback getGattCallback() {
        return mGattCallback;
    }

    private final BleManagerGattCallback mGattCallback = new BleManagerGattCallback() {
        @Override
        protected void initialize() {
            Log.e(TAG, "initialize");

            if (mNotifyCharacteristic!=null) {
                //手环发消息过来
                setNotificationCallback(mNotifyCharacteristic).with((device, data) -> mCallbacks.onDataReceived(device, data));
                //开启消息通知
                enableNotifications(mNotifyCharacteristic).enqueue();
            }



            //在这里开启通知。三星可以两个全部开 ， Google pixel 只开一个就不能开第二个,然后就连接失败 。重启蓝牙可以解决。

            if (otas_rx_cmd_Characteristic!=null) {
                Log.e(TAG,"开启消息通知3");
                //3
                setNotificationCallback(otas_rx_cmd_Characteristic).with((device, data) -> mCallbacks.onDataReceived3(device,data));
                //开启消息通知
                enableNotifications(otas_rx_cmd_Characteristic).enqueue();
            }


            if (otas_rx_dat_Characteristic!=null) {
                Log.e(TAG,"开启消息通知4");
                //4
                setNotificationCallback(otas_rx_dat_Characteristic).with((device, data) -> mCallbacks.onDataReceived4(device,data));
                //开启消息通知
                enableNotifications(otas_rx_dat_Characteristic).enqueue();
            }

        }

        @Override
        protected boolean isRequiredServiceSupported(@NonNull BluetoothGatt gatt) {
            Log.e(TAG, "isRequiredServiceSupported");
            final BluetoothGattService service = gatt.getService(SERVICE_UUID);
            final BluetoothGattService ota_service = gatt.getService(ota_service_uuid);
            if (service != null) {
                Log.e(TAG, "service != null");
                mWriteCharacteristic = service.getCharacteristic(WRITE_CHARACTERISTIC_UUID);
                mNotifyCharacteristic = service.getCharacteristic(NOTIFY_CHARACTERISTIC_UUID);
            }


            if (ota_service != null) {
                Log.e(TAG, "ota_service != null");
                otas_tx_cmd_Characteristic = ota_service.getCharacteristic(otas_tx_cmd_uuid);
                otas_tx_dat_Characteristic = ota_service.getCharacteristic(otas_tx_dat_uuid);
                otas_rx_cmd_Characteristic = ota_service.getCharacteristic(otas_rx_cmd_uuid);
                otas_rx_dat_Characteristic = ota_service.getCharacteristic(otas_rx_dat_uuid);

                SPUtils.putBoolean(getContext(), SPUtils.SUPPORTOTA, true);

            } else {
                SPUtils.putBoolean(getContext(), SPUtils.SUPPORTOTA, false);
            }


            return true;
        }

        @Override
        protected void onDeviceDisconnected() {
            mWriteCharacteristic = null;
            mNotifyCharacteristic = null;
        }
    };


    public void sendOtaCmd(final byte[] bytes) {
        if (otas_tx_cmd_Characteristic == null)
            return;

        otas_tx_cmd_Characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);

        final WriteRequest request = writeCharacteristic(otas_tx_cmd_Characteristic, bytes)
                .with((device, data) -> mCallbacks.onDataSent1(device, data));
        if (bytes.length > 20) {
            request.split();
            Log.i(TAG, "split");
        }
        request.enqueue();
    }


    public void send(final byte[] bytes) {
        if (mWriteCharacteristic == null)
            return;

        mWriteCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);

        final WriteRequest request = writeCharacteristic(mWriteCharacteristic, bytes)
                .with((device, data) -> mCallbacks.onDataSent(device, data));
        if (bytes.length > 20) {
            request.split();
            Log.i(TAG, "split");
        }
        request.enqueue();
    }

    @Override
    public void log(int priority, @NonNull String message) {
        super.log(priority, message);
        Log.i(TAG, "log->" + message);
    }

    public void sendOtaData(byte[] bytes) {
        if (otas_tx_dat_Characteristic == null)
            return;

        otas_tx_dat_Characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);

        final WriteRequest request = writeCharacteristic(otas_tx_dat_Characteristic, bytes)
                .with((device, data) -> mCallbacks.onDataSent2(device, data));
        if (bytes.length > 20) {
            request.split();
            Log.i(TAG, "split");
        }
        request.enqueue();
    }

}
